#include<gflags/gflags.h>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include "student.hxx"
#include "student-odb.hxx"


DEFINE_string(host, "127.0.0.1", "这是MySQL服务器地址");
DEFINE_int32(port, 0, "这是MySQL服务端口号");
DEFINE_string(db, "TestDB", "数据库默认名称");
DEFINE_string(user, "root", "mysql默认用户名");
DEFINE_string(password, "3202126231", "mysql用户密码");
DEFINE_string(cset,"utf8","mysql默认字符集");
DEFINE_int32(max_pool,3,"连接池最大连接数量");


void insert_classes(odb::mysql::database&db){
    try{
        // 3. 获取事务对象，开启事务
        odb::transaction trans(db.begin());
        Classes c1("三年级一班");
        Classes c2("三年级二班");
        db.persist(c1);
        db.persist(c2);
        // 5. 提交事务
        trans.commit();
    }catch(std::exception&e){
        std::cout<<"班级数据导入失败："<<e.what()<<std::endl;
    }

}

void insert_studebt(odb::mysql::database&db){
    try{
        // 3. 获取事务对象，开启事务
        odb::transaction trans(db.begin());
        Student s1("张三",0001,18,1);
        Student s2("李四",0002,19,1);
        Student s3("王五",0003,17,1);
        Student s4("鸡哥",0004,18,2);
        Student s5("周杰伦",0005,18,2);
        db.persist(s1);
        db.persist(s2);
        db.persist(s3);
        db.persist(s4);
        db.persist(s5);
        // 5. 提交事务
        trans.commit();
    }catch(std::exception&e){
        std::cout<<"学生数据导入失败："<<e.what()<<std::endl;
    }
}

Student select_studebt(odb::mysql::database&db){
    Student res;
    try{
        // 3. 获取事务对象，开启事务
        odb::transaction trans(db.begin());
        typedef odb::query<Student> query;
        typedef odb::result<Student> result;
        result r(db.query<Student>(query::name=="张三"));
        if(r.size()!=1){
            std::cout<<"查询结果不符和实际"<<std::endl;
            return Student();
        }
        res=*r.begin();
        // 5. 提交事务
        trans.commit();
    }catch(std::exception&e){
        std::cout<<"学生信息查询失败："<<e.what()<<std::endl;
    }
    return res;
}
Student select_studebt_classes(odb::mysql::database&db){
    Student res;
    try{
        // 3. 获取事务对象，开启事务
        odb::transaction trans(db.begin());
        typedef odb::query<Student> query;
        typedef odb::result<Student> result;
        result r(db.query<Student>(query::classes_id==1));
        for(auto it=r.begin();it!=r.end();it++){
            std::cout << it->name() << std::endl;
            std::cout << it->sn() << std::endl;
            std::cout << it->classes_id() << std::endl;
            if (it->age())
                std::cout << *(it->age()) << std::endl;
        }
        res=*r.begin();
        // 5. 提交事务
        trans.commit();
    }catch(std::exception&e){
        std::cout<<"班级信息查询失败："<<e.what()<<std::endl;
    }
    return res;
}
void update_student(odb::mysql::database&db,const Student &stu){
    try{
        // 3. 获取事务对象，开启事务
        odb::transaction trans(db.begin());
        // 5. 提交事务
        db.update(stu);
        trans.commit();
    }catch(std::exception&e){
        std::cout<<"学生信息查询失败："<<e.what()<<std::endl;
    }
    return ;
}
void classes_student(odb::mysql::database&db){
    try{
        odb::transaction trans(db.begin());
        typedef odb::query<struct classes_student> query;
        typedef odb::result<struct classes_student> result;
        result r(db.query<struct classes_student>(query::classes::id==1));
        for(auto it=r.begin();it!=r.end();it++){
            std::cout << it->classes_name << std::endl;
            std::cout << it->name << std::endl;
            std::cout << it->id << std::endl;
            std::cout << it->sn << std::endl;

            if (it->_age)
                std::cout << *(it->_age) << std::endl;
        }

    }catch(std::exception&e){
        std::cout<<"学生信息查询失败："<<e.what()<<std::endl;
    }
}
int main(int argc,char*argv[]){
    google::ParseCommandLineFlags(&argc, &argv, true);
    // 数据库操作流程
    //1. 构造连接池对象
    std::unique_ptr<odb::mysql::connection_pool_factory> cpf(new odb::mysql::connection_pool_factory(FLAGS_max_pool,0));
    //2. 构造数据库操作database对象 
    odb::mysql::database db(
        FLAGS_user,
        FLAGS_password,
        FLAGS_db,
        FLAGS_host,
        FLAGS_port,
        "",
        FLAGS_cset,
        0,
        std::move(cpf) );
    //4. 数据库操作 
    // insert_classes(db);

    // insert_studebt(db);

    // auto stu=select_studebt(db);
    // std::cout<<stu.name()<<std::endl;
    // std::cout<<stu.sn()<<std::endl;
    // std::cout<<stu.classes_id()<<std::endl;
    // if(stu.age())std::cout<<*stu.age()<<std::endl;

    //select_studebt_classes(db);

    // auto stu=select_studebt(db);
    // stu.name("小黑子");
    // update_student(db,stu);
    //5. 提交事务
    classes_student(db);

    return 0;
}